package events

import (
	"context"
	"sync"
	"time"

	"github.com/google/uuid"

	"BookStack/pkg/utils"
)

// Event 事件接口
type Event interface {
	// GetID 获取事件ID
	GetID() string
	// GetType 获取事件类型
	GetType() string
	// GetPayload 获取事件负载
	GetPayload() interface{}
	// GetTimestamp 获取事件时间戳
	GetTimestamp() time.Time
}

// EventHandler 事件处理函数
type EventHandler func(ctx context.Context, event Event) error

// Publisher 事件发布者接口
type Publisher interface {
	// Subscribe 订阅事件，返回订阅ID
	Subscribe(eventType string, handler EventHandler) error
	// Unsubscribe 取消订阅
	Unsubscribe(eventType string, handler EventHandler) error
	// Publish 同步发布事件
	Publish(ctx context.Context, event Event) error
	// AsyncPublish 异步发布事件
	AsyncPublish(ctx context.Context, event Event) error
}

// BaseEvent 基础事件结构体
type BaseEvent struct {
	ID        string      `json:"id"`
	Type      string      `json:"type"`
	Payload   interface{} `json:"payload"`
	Timestamp time.Time   `json:"timestamp"`
}

// GetID 实现Event接口 - 获取事件ID
func (e *BaseEvent) GetID() string {
	return e.ID
}

// GetType 实现Event接口 - 获取事件类型
func (e *BaseEvent) GetType() string {
	return e.Type
}

// GetPayload 实现Event接口 - 获取事件负载
func (e *BaseEvent) GetPayload() interface{} {
	return e.Payload
}

// GetTimestamp 实现Event接口 - 获取事件时间戳
func (e *BaseEvent) GetTimestamp() time.Time {
	return e.Timestamp
}

// NewEvent 创建新事件
func NewEvent(eventType string, payload interface{}) Event {
	now, _ := time.Parse(utils.StandardTimeFormat, utils.Now())
	return &BaseEvent{
		ID:        uuid.New().String(),
		Type:      eventType,
		Payload:   payload,
		Timestamp: now,
	}
}

// EventPublisher 事件发布者实现
type EventPublisher struct {
	handlers map[string][]EventHandler
	mu       sync.RWMutex
}

// NewPublisher 创建事件发布者
func NewPublisher() Publisher {
	return &EventPublisher{
		handlers: make(map[string][]EventHandler),
	}
}

// Subscribe 订阅事件
func (p *EventPublisher) Subscribe(eventType string, handler EventHandler) error {
	p.mu.Lock()
	defer p.mu.Unlock()

	// 检查处理器是否已存在
	handlers := p.handlers[eventType]
	for _, h := range handlers {
		if &h == &handler {
			return nil // 处理器已存在，直接返回
		}
	}

	// 添加新的处理器
	p.handlers[eventType] = append(handlers, handler)
	return nil
}

// Unsubscribe 取消订阅事件
func (p *EventPublisher) Unsubscribe(eventType string, handler EventHandler) error {
	p.mu.Lock()
	defer p.mu.Unlock()

	handlers := p.handlers[eventType]
	if len(handlers) == 0 {
		return nil
	}

	// 查找并移除处理器
	newHandlers := make([]EventHandler, 0, len(handlers))
	for _, h := range handlers {
		if &h != &handler {
			newHandlers = append(newHandlers, h)
		}
	}

	p.handlers[eventType] = newHandlers
	return nil
}

// Publish 同步发布事件
func (p *EventPublisher) Publish(ctx context.Context, event Event) error {
	p.mu.RLock()
	handlers := p.handlers[event.GetType()]
	p.mu.RUnlock()

	for _, handler := range handlers {
		if err := handler(ctx, event); err != nil {
			return err
		}
	}
	return nil
}

// AsyncPublish 异步发布事件
func (p *EventPublisher) AsyncPublish(ctx context.Context, event Event) error {
	p.mu.RLock()
	handlers := p.handlers[event.GetType()]
	p.mu.RUnlock()

	for _, handler := range handlers {
		go func(h EventHandler) {
			_ = h(ctx, event)
		}(handler)
	}
	return nil
}

// UserEventPayload 用户事件通用负载
type UserEventPayload struct {
	UserID    uint      `json:"user_id"`
	Username  string    `json:"username"`
	Email     string    `json:"email,omitempty"`
	Timestamp time.Time `json:"timestamp"`
}

// 事件类型常量
const (
	// 用户相关事件
	UserRegisteredEvent      = "user.registered"
	UserLoggedInEvent        = "user.logged_in"
	UserProfileUpdatedEvent  = "user.profile_updated"
	UserPasswordChangedEvent = "user.password_changed"
	UserDeletedEvent         = "user.deleted"

	// 其他事件类型可以在这里继续定义
)
